import { useEffect, useState } from 'react';
import type { ReactElement } from 'react';
import {
    Alert,
    Card,
    CardBody,
    CardHeader,
    CardTitle,
    Flex,
    FlexItem,
} from '@patternfly/react-core';
import { differenceInMinutes } from 'date-fns';

import { fetchVulnerabilityDefinitionsInfo } from 'services/IntegrationHealthService';
import type { ScannerComponent } from 'services/IntegrationHealthService';
import { getAxiosErrorMessage } from 'utils/responseErrorUtils';

import { ErrorIcon, SpinnerIcon, healthIconMap } from '../CardHeaderIcons';

const dayInMinutes = 24 * 60;

type VulnerabilityDefinitionsHealthCardProps = {
    component: ScannerComponent;
    pollingCount: number;
};

const VulnerabilityDefinitionsHealthCard = ({
    component,
    pollingCount,
}: VulnerabilityDefinitionsHealthCardProps): ReactElement => {
    const [isFetching, setIsFetching] = useState(false);
    const [errorMessageFetching, setErrorMessageFetching] = useState('');
    const [lastUpdatedTimestamp, setLastUpdatedTimestamp] = useState('');
    const [currentDatetime, setCurrentDatetime] = useState<Date | null>(null);

    const title =
        component === 'SCANNER_V4'
            ? 'Scanner V4 Vulnerabilities'
            : 'StackRox Scanner Vulnerability Definitions';

    useEffect(() => {
        setIsFetching(true);
        fetchVulnerabilityDefinitionsInfo(component)
            .then((info) => {
                setErrorMessageFetching('');
                setLastUpdatedTimestamp(info.lastUpdatedTimestamp);
                setCurrentDatetime(new Date());
            })
            .catch((error) => {
                setErrorMessageFetching(getAxiosErrorMessage(error));
                setLastUpdatedTimestamp('');
                setCurrentDatetime(null);
            })
            .finally(() => {
                setIsFetching(false);
            });
    }, [component, pollingCount]);

    /*
     * Wait for isFetching only until response to the initial request.
     * Otherwise timestamp temporarily disappears during each subsequent request.
     */
    const isFetchingInitialRequest = isFetching && pollingCount === 0;

    // Beware: the order of the arguments in date-fns@1 (later, earlier)
    // will be reversed in date-fns@2 to differenceInMinutes(earlier, later).
    const isUpToDate =
        lastUpdatedTimestamp &&
        currentDatetime &&
        differenceInMinutes(currentDatetime, lastUpdatedTimestamp) < dayInMinutes;

    const icon = isFetchingInitialRequest
        ? SpinnerIcon
        : errorMessageFetching
          ? ErrorIcon
          : healthIconMap[isUpToDate ? 'success' : 'danger'];

    return (
        <Card isCompact>
            <CardHeader>
                <Flex className="pf-v5-u-flex-grow-1">
                    <FlexItem>{icon}</FlexItem>
                    <FlexItem>
                        <CardTitle component="h2">{title}</CardTitle>
                    </FlexItem>
                    {lastUpdatedTimestamp && currentDatetime && (
                        <>
                            <FlexItem>{isUpToDate ? 'up to date' : 'out of date'}</FlexItem>
                            <FlexItem align={{ default: 'alignRight' }}>
                                {lastUpdatedTimestamp}
                            </FlexItem>
                        </>
                    )}
                </Flex>
            </CardHeader>
            {errorMessageFetching && (
                <CardBody>
                    <Alert isInline variant="warning" title={errorMessageFetching} component="p" />
                </CardBody>
            )}
        </Card>
    );
};

export default VulnerabilityDefinitionsHealthCard;
